package com.meirengu.webview.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.meirengu.common.RedisClient;
import com.meirengu.service.impl.BaseServiceImpl;
import com.meirengu.utils.DateUtils;
import com.meirengu.utils.NumberUtil;
import com.meirengu.utils.StringUtil;
import com.meirengu.utils.ValidatorUtil;
import com.meirengu.webview.dao.KwChannelDataDao;
import com.meirengu.webview.dao.UserDao;
import com.meirengu.webview.dao.UserInfoDao;
import com.meirengu.webview.model.KwChannel;
import com.meirengu.webview.model.User;
import com.meirengu.webview.model.UserInfo;
import com.meirengu.webview.service.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class InformationServiceImpl extends BaseServiceImpl<User> implements InformationService {

    private static final Logger logger = LoggerFactory.getLogger(InformationServiceImpl.class);

    @Autowired
    UserDao userDao;

    @Autowired
    KwChannelService kwChannelService;

    @Autowired
    KwChannelDataService kwChannelDataService;

    @Autowired
    UserService userService;

    @Autowired
    UserInfoDao userInfoDao;

    @Autowired
    RedisClient redisClient;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    LmUserBaseService lmUserBaseService;

    @Autowired
    KwChannelDataDao kwChannelDataDao;

    @Autowired
    private AsyncService asyncService;


    public boolean needSms(String mobile, BigDecimal money) {
        // 1.手机号是否已注册
        boolean flag = isExist(mobile);
        if (flag) {
            // 2.手机号已注册，判断是否已完善信息
            User user = userService.getByMobile(mobile);
            if (user == null) {
                logger.info("redis中有用户信息，数据库中无用户信息:{}", mobile);
                // 手机号未注册,需要发送
                return true;
            } else {
                if (StringUtils.isBlank(user.getName())) {
                    // 3.该手机号用户未完善信息,判断贷款金额是否大于10000
                    int a = money.compareTo(new BigDecimal(10000));
                    if (a == -1) {
                        logger.info("该手机号用户未完善信息,无需发送短信,电话:{},金额:{} 姓名:{}", mobile, money, user.getName());
                        // 贷款金额小于10000,无需发送
                        return false;
                    } else {
                        logger.info("该手机号用户未完善信息,发送短信,电话:{},金额:{} 姓名:{}", mobile, money, user.getName());
                        // 贷款金额大于10000,需要发送
                        return true;
                    }
                } else {
                    logger.info("该手机号用户已完善信息,电话:{}, 姓名:{}", mobile, user.getName());
                    // 该手机号用户已完善信息,无需发送
                    return false;
                }
            }

        } else {
            // 手机号未注册,需要发送
            return true;
        }
    }

    /**
     * 根据是否已存在手机号，是否已完善信息来判断是否应该发送短信
     */
    public boolean needSms(String mobile) {
        // 1.手机号是否已注册
        boolean flag = isExist(mobile);
        if (flag) {
            // 2.手机号已注册，判断是否已完善信息
            User user = userService.getByMobile(mobile);
            if (user == null) {
                logger.info("redis中有用户信息，数据库中无用户信息:{}", mobile);
                // 手机号未注册,需要发送
                return true;
            } else {
                String userName = user.getName();
                logger.info("该手机号信息，电话:{}，姓名:{}", mobile, userName);
                return StringUtils.isBlank(userName);
            }
        } else {
            // 手机号未注册,需要发送
            return true;
        }
    }

    public boolean isExist(String mobile) {
        boolean flag = false;
        if (redisClient.exists("kwdRegister")) {
            flag = redisClient.sismember("kwdRegister", mobile);
            if (flag) {
                logger.debug("用户已注册:{}", mobile);
                return flag;
            }
            flag = redisClient.sismember("mdzjRegister", mobile);
            if (flag) {
                logger.debug("用户已存在秒单之家:{}", mobile);
                return flag;
            }
        } else {
            User user = userService.getByMobile(mobile);
            if (user != null && user.getId() != null) {
                UserInfo userInfo = userInfoService.getByUserId(user.getId());
                if (userInfo != null && userInfo.getId() != null) {
                    flag = true;
                    return flag;
                }
            }
            Integer count = lmUserBaseService.isExist(mobile);
            if (count != null && count == 1) {
                flag = true;
                return flag;
            }
        }
        logger.info("用户未注册:{}", mobile);
        return flag;
    }


    @Override
    public User getByMobile(String mobile) {
        return userDao.getByMobile(mobile);
    }

    @Override
    public int signUp(String phone, String cid, String ip, String money) throws Exception {
        //查询渠道
        KwChannel kwChannel = kwChannelService.getByCode(cid);
        User user = new User();
        user.setMobile(phone);
        user.setIp(ip);
        user.setChannelCode(cid);
        //期望金额
        BigDecimal _money = new BigDecimal(money);
        if (kwChannel != null && StringUtils.isNotBlank(kwChannel.getId())) {
            user.setChannelId(kwChannel.getId());
            user.setChannelName(kwChannel.getChannelName());
        }
        int code = insert(user);
        //insert user_info
        //User user1 = userDao.getByMobile(user.getMobile());
        if (user.getId() != null) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(user.getId());
            userInfo.setExpectAmount(_money);
            userInfo.setSubmitStage(1);
            userInfoDao.insert(userInfo);
            asyncService.sendMQAsync(user.getId());
        }
        if (kwChannel != null && StringUtils.isNotBlank(kwChannel.getId())) {
            Map<String, String> map = new HashMap<>();
            map.put("channelId", kwChannel.getId());
            map.put("registNum", "1");
            map.put("visitNum", "1");
            kwChannelDataDao.addNum(map);
        }
        return code;
    }

    @Override
    public int signUp(String phone, String cid, String ip) throws Exception {
        KwChannel kwChannel = null;
        //查询渠道
        if (StringUtils.isNotEmpty(cid)) {
            kwChannel = kwChannelService.getByCode(cid);
        }
        User user = new User();
        user.setMobile(phone);
        user.setIp(ip);
        user.setChannelCode(cid);
        //期望金额
        if (kwChannel != null && StringUtils.isNotBlank(kwChannel.getId())) {
            user.setChannelId(kwChannel.getId());
            user.setChannelName(kwChannel.getChannelName());
        }
        int code = insert(user);
        //insert user_info
        //User user1 = userDao.getByMobile(user.getMobile());
        if (user.getId() != null) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(user.getId());
            userInfo.setSubmitStage(1);
            userInfoDao.insert(userInfo);
            asyncService.sendMQAsync(user.getId());
        }
        if (kwChannel != null && StringUtils.isNotBlank(kwChannel.getId())) {
            Map<String, String> map = new HashMap<>();
            map.put("channelId", kwChannel.getId());
            map.put("registNum", "1");
            map.put("visitNum", "1");
            kwChannelDataDao.addNum(map);
        }
        return code;
    }

    public int updateUser(String phone, String name, Integer sex, String city, String birthday, String userAgent) throws Exception {
        User user = getByMobile(phone);
        if (user == null) return 0;
        user.setMobile(phone);
        user.setName(name);
        user.setSex(sex);
        Date date = DateUtils.getDate(birthday, "yyyy-MM-dd");
        logger.debug("birth:" + date);
        user.setBirthday(date);
        int age = getAge(user.getBirthday());
        user.setAge(age);
        user.setCity(city);
        user.setUserAgent(userAgent);
        return userDao.update(user);
    }

    public int complement(String _phone,
                          String _name,
                          String _sex,
                          String _city,
                          String _areaCode,
                          String _areaName,
                          String _profession,
                          String _socialSecurity,
                          String _housingFund,
                          String _birthday,
                          String _income,
                          String _insurance,
                          String _housingType,
                          String _hasCars,
                          String _creditSituation,
                          String _paytype,
                          String _worklong,
                          String _acceptsafety,
                          String _lifeInsurance,
                          String _isAtom,
                          String _enpass,
                          String _ip,
                          String idCard) throws Exception {

        //手机号
        String phoneno = _phone;
        User userfore = userDao.getByMobile(phoneno);
        if (userfore == null) {
            logger.warn("user phone is not exit " + phoneno);
            return 0;
        }
        UserInfo userInfo = userInfoDao.getByUserId(userfore.getId());
        if (!NumberUtil.isNullOrZero(userInfo.getSubmitStage()) && userInfo.getSubmitStage() == 2) {
            logger.warn("用户信息已完善,不需要完善信息 " + phoneno);
            return 0;
        }
        //姓名
        String name = _name;
        //期望金额
        //BigDecimal money = new BigDecimal(_money);
        //性别 0 男    1女
        Integer sex = StringUtil.getIntValue(_sex);
        //所在城市
        String city = _city;
        //职业  0白领   1私企业主  2公务员
        Integer profession = StringUtil.getIntValue(_profession);
        //社保   0无社保   1一年以内    2一年以上
        Integer socialSecurity = StringUtil.getIntValue(_socialSecurity);
        //住房公积金   0无公积金   1一年以内    2一年以上
        Integer housingFund = StringUtil.getIntValue(_housingFund);
        //生日 格式“1991-08-09”
        Date birthday = DateUtils.getDate(_birthday, null);
        //月薪   1 3000以下  2 3000-5000  3 5001-8000   4 8001-10000  5 1w以上
        Integer income = StringUtil.getIntValue(_income);
        //勾选意外险
        Integer insurance = StringUtil.getIntValue(_insurance);
        //名下房产  1 无房   2 有房贷   3有房无贷
        Integer housingType = StringUtil.getIntValue(_housingType);
        //名下车   1 无车   2 有车贷    3有车无贷
        Integer hasCar = StringUtil.getIntValue(_hasCars);
        //信用情况 1无信用卡无贷款   2有信用卡或贷款
        Integer creditSituation = StringUtil.getIntValue(_creditSituation);
        //工资发放方式  1 银行转账  2 现金发放
        Integer paytype = StringUtil.getIntValue(_paytype);
        //工作时长  6 6个月内   12 12月内    24 一年以上
        Integer worklong = StringUtil.getIntValue(_worklong);
        //接受用户协议
        Integer acceptsafety = StringUtil.getIntValue(_acceptsafety);

        Integer enpass = 1;
        //寿险  1 无寿险   2 寿险2400以下   3 寿险2400以上
        Integer lifeInsurance = StringUtil.getIntValue(_lifeInsurance);
        //是否用过微粒贷 1是，2否
        Integer isAtom = StringUtil.getIntValue(_isAtom);
        //地区code
        Integer areaCode = StringUtil.getIntValue(_areaCode);
        //地区name
        String areaName = _areaName;
        //如果name为空，从redis中取出数据
        String ip = _ip;

        //logger.debug("userInfo:"+userInfo.toString());
        if (userInfo != null) {
            //用户详细信息
            userInfo.setPolicy(lifeInsurance);
            userInfo.setCredit(creditSituation);
            userInfo.setHouse(housingType);
            userInfo.setCar(hasCar);
            userInfo.setFund(housingFund);
            userInfo.setSocialSecurity(socialSecurity);
            userInfo.setOccupation(profession);
            userInfo.setSalaryMethod(paytype);
            userInfo.setWorkDuration(worklong);
            userInfo.setSalary(income);
            userInfo.setWxloan(isAtom);
            userInfo.setScity(city);
            userInfo.setBirthday(birthday);
            userInfo.setBusinessDuration(enpass);
            userInfo.setIp(ip);
            userInfo.setAreaCode(areaCode);
            userInfo.setAreaName(areaName);
            userInfo.setSubmitStage(2);
            if (ValidatorUtil.isIDCard(idCard)) {
                userInfo.setIdCard(idCard);
            }
            /*手机归属地*/
            String hd = phoneno.substring(0, 7);
            String mobileJson = redisClient.get("mobilehd" + hd);
            if (StringUtils.isNotBlank(mobileJson)) {
                JSONObject jsonObject = JSON.parseObject(mobileJson);
                if (jsonObject != null) {
                    userInfo.setMobileRegistration(jsonObject.getString("city"));
                }
            }
            userInfoDao.update(userInfo);

            //是否O2O
            boolean O2Oflag = false;
            if (lifeInsurance.intValue() != 1 || housingType.intValue() != 1 || hasCar.intValue() != 1) {
                O2Oflag = true;
            }
            //更新产品申请量
            if (StringUtils.isNotBlank(userfore.getChannelId())) {
                //logger.debug("更新产品申请量 ");
                int code = kwChannelDataService.updateApplyNum(userfore.getChannelId(), O2Oflag);

            }
            //异步发送渠道
            userInfoService.sendAsyn(userfore.getId());
        }
        return 1;
    }

    //由出生日期获得年龄
    public int getAge(Date birthDay) throws Exception {
        Calendar cal = Calendar.getInstance();

        if (cal.before(birthDay)) {
            throw new IllegalArgumentException(
                    "The birthDay is before Now.It's unbelievable!");
        }
        int yearNow = cal.get(Calendar.YEAR);
        int monthNow = cal.get(Calendar.MONTH);
        int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH);
        cal.setTime(birthDay);

        int yearBirth = cal.get(Calendar.YEAR);
        int monthBirth = cal.get(Calendar.MONTH);
        int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);

        int age = yearNow - yearBirth;

        if (monthNow <= monthBirth) {
            if (monthNow == monthBirth) {
                if (dayOfMonthNow < dayOfMonthBirth) age--;
            } else {
                age--;
            }
        }
        return age;
    }

}

